#include "rest.h"
#include "Tools.h"

REST::REST(QObject* parent)
    : QObject(parent)
{
    base = new APIBase(this);
}

REST::~REST()
{
    qout << "~REST()";
}

/**
 * @brief 设置REST的配置文件
 * @param json
 */
void REST::setRESTJson(const QByteArray& json)
{
    // 尝试解析
    QJsonParseError parseError;
    auto jsonDoc = QJsonDocument::fromJson(json, &parseError);
    if (parseError.error != QJsonParseError::NoError) {
        qout << parseError.errorString() << parseError.offset;
        return;
    }

    // 分类型处理
    if (jsonDoc.isObject()) {
        auto jsonProfileObj = jsonDoc.object();

    } else if (jsonDoc.isArray()) {
        auto jsonProfileArray = jsonDoc.array();
        parseRESTArray(jsonProfileArray);
    }
}

/**
 * @brief 启动定时器
 */
void REST::start()
{
    for (int i = 0; i < timers.size(); ++i) {
        timers.at(i)->start();
    }
}

/**
 * @brief 停止定时器
 */
void REST::stop()
{
    for (int i = 0; i < timers.size(); ++i) {
        timers.at(i)->stop();
    }
}

/**
 * @brief 解析REST的配置json,并启动定时器
 * @param jsonProfileArray
 */
void REST::parseRESTArray(QJsonArray& jsonProfileArray)
{
    for (int i = 0; i < jsonProfileArray.size(); ++i) {
        auto json = jsonProfileArray.at(i).toObject();
        parseRESTObj(json);
    }
}

void REST::parseRESTObj(QJsonObject& jsonObj)
{
    QString equipMark = jsonObj["equipMark"].toString();
    QString IP = jsonObj["IP"].toString();
    QString Port = jsonObj["Port"].toString();
    UrlEquipMarkMap.insert(IP, equipMark);

    QJsonArray intfsArr = jsonObj["intfs"].toArray();
    for (int i = 0; i < intfsArr.size(); ++i) {
        QJsonObject intfObj = intfsArr.at(i).toObject();
        QString intfUrl = intfObj["url"].toString();
        QString intfMethod = intfObj["method"].toString();
        int intfTimerInterval = intfObj["timerInterval"].toInt();
        QString paramsStr = QJsonDocument(intfObj["params"].toObject()).toJson();

        startRESTMethod(IP + ":" + Port + intfUrl, intfMethod, paramsStr, intfTimerInterval);
    }
}

void REST::startRESTMethod(QString url, QString method, QString paramsStr, int intfTimerInterval)
{
    QTimer* timer = new QTimer(this);
    timer->setInterval(intfTimerInterval);
    //    timer->setSingleShot (true);
    timers << timer;

    connect(timer, &QTimer::destroyed,
        [&] {
            qout << "QTimer destroyed";
        });

    connect(timer, &QTimer::timeout,
        [=] {
            QNetworkReply* reply = 0;
            base->setKnownHeaderName(APIBase::KnownHeaders::ContentType, "application/json");
            if (method == "POST") {
                reply = base->post(QUrl(url), paramsStr.toUtf8());
            } else if (method == "GET") {
                reply = base->get(QUrl(url));
            }
            //            qout << reply;

            if (!reply)
                return;
            connectNetworkReply(reply);
        });
}

void REST::connectNetworkReply(QNetworkReply* reply)
{
    connect(reply, &QNetworkReply::finished,
        this, [=] {
            auto urlStr = reply->url().toString();

            // "https://jsonplaceholder.typicode.com:443/posts"
            // "http://jsonplaceholder.typicode.com:80/posts"
            auto ip = urlStr.left(urlStr.indexOf(':', 6));
            UrlEquipMarkMap.value(ip, QString());
            // qout << reply->operation(); 获取响应的方法
            auto replydata = reply->readAll();

            // 定制的响应格式json
            QJsonObject sendObj;
            QJsonObject headObj;
            headObj["equipmentCode"] = UrlEquipMarkMap.value(ip, QString());
            headObj["protocol"] = QStringLiteral("REST");
            headObj["receiveDateTime"] = QDateTime::currentDateTime()
                                             .toString("yyyy-MM-dd HH:mm:ss");
            headObj["status"] = 1;

            sendObj["header"] = headObj;
            sendObj["body"] = QString(replydata.toBase64());

            // 发射REST服务器响应的结果
            emit RESTReply(QJsonDocument(sendObj).toJson(QJsonDocument::Compact));
        });
}
